package com.sczmgk.hotline_pzh.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.media.ThumbnailUtils;
import android.text.TextUtils;
import android.util.Base64;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

public class BitmapUtils {
    private static final String TAG = "BitmapUtils";

    private static final Object OBJECT_LOCKED = new Object();

    public static final String EXTENSION_IMG_PNG = "png";

    public static final String EXTENSION_IMG_JPEG = "jpg";

    /**
     * 改变图片的尺寸
     *
     * @param maxWidth  最大宽度
     * @param maxHeight 最大高度
     * @param oldBitmap 原图
     * @return 返回变更后的图片
     */
    public static Bitmap changeBitmapSize(int maxWidth, int maxHeight, Bitmap oldBitmap) {
        if (oldBitmap == null || oldBitmap.isRecycled()) {
            return null;
        }
        int[] measureArrary = BitmapUtils.getMeasureSize(oldBitmap.getWidth(), oldBitmap.getHeight(), maxWidth, maxHeight);
        if (measureArrary != null) {
            oldBitmap = BitmapUtils.changeBitmapSizeFixed(measureArrary[0], measureArrary[1], oldBitmap);
        }
        return oldBitmap;
    }

    /**
     * 根据图片路径取得图片bitMap
     *
     * @param imgPath   图片路径
     * @param maxWidth  最大宽度
     * @param maxHeight 最大高度
     * @return bitmap
     */
    public static Bitmap getBitmap(String imgPath, int maxWidth, int maxHeight) {
        return getBitmap(imgPath, maxWidth, maxHeight, null);
    }

    /**
     * 将字节数组转成bitMap
     *
     * @param date
     * @param maxWidth  最大宽度
     * @param maxHeight 最大高度
     * @return bitmap
     */
    public static Bitmap getBitmap(byte[] date, int maxWidth, int maxHeight) {
        return getBitmap(date, maxWidth, maxHeight, null);
    }

    /**
     * 取得图片
     *
     * @param imgPath
     * @param maxWidth
     * @param maxHeight
     * @param options
     * @return
     */
    public static Bitmap getBitmap(String imgPath, int maxWidth, int maxHeight, BitmapFactory.Options options) {
        synchronized (OBJECT_LOCKED) {
            Bitmap bm = BitmapUtils.getBitmapBySampleSize(imgPath, maxWidth, maxHeight, options);
            System.gc();
            return BitmapUtils.changeBitmapSize(maxWidth, maxHeight, bm);
        }
    }

    /**
     * 取得图片
     *
     * @param date
     * @param maxWidth
     * @param maxHeight
     * @param options
     * @return
     */
    public static Bitmap getBitmap(byte[] date, int maxWidth, int maxHeight, BitmapFactory.Options options) {
        Bitmap bm = BitmapUtils.getBitmapBySampleSize(date, maxWidth, maxHeight, options);
        return BitmapUtils.changeBitmapSize(maxWidth, maxHeight, bm);
    }

    /**
     * 根据options及所需的尺寸取得图片
     *
     * @param resource
     * @param context
     * @param maxWidth
     * @param maxHeight
     * @param options
     * @return
     */
    public static Bitmap getBitmap(int resource, Context context, int maxWidth, int maxHeight, BitmapFactory.Options options) {
        Bitmap bm = BitmapUtils.getBitmapBySampleSize(context, resource, maxWidth, maxHeight, options);
        return BitmapUtils.changeBitmapSize(maxWidth, maxHeight, bm);
    }

    private static Bitmap getBitmapBySampleSize(String imgPath, int maxWidth, int maxHeight, BitmapFactory.Options options) {
        BitmapFactory.Options tempOptions = new BitmapFactory.Options();
        tempOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imgPath, tempOptions);
        // Calculate inSampleSize
        int inSampleSize = calculateInSampleSize(tempOptions, maxWidth, maxHeight);

        if (options != null) {
            tempOptions = options;
        }
        tempOptions.inSampleSize = inSampleSize;
        // Decode bitmap with inSampleSize set
        tempOptions.inJustDecodeBounds = false;

        return BitmapFactory.decodeFile(imgPath, tempOptions);
    }

    /**
     * 取得图片数组的sampleSize
     *
     * @param data
     * @param maxWidth
     * @param maxHeight
     * @param options
     * @return
     */
    private static Bitmap getBitmapBySampleSize(byte[] data, int maxWidth, int maxHeight, BitmapFactory.Options options) {
        BitmapFactory.Options tempOptions = new BitmapFactory.Options();
        tempOptions.inJustDecodeBounds = true;

        BitmapFactory.decodeByteArray(data, 0, data.length, tempOptions);
        // Calculate inSampleSize
        int inSampleSize = calculateInSampleSize(tempOptions, maxWidth, maxHeight);

        if (options != null) {
            tempOptions = options;
        }
        tempOptions.inSampleSize = inSampleSize;
        // Decode bitmap with inSampleSize set
        tempOptions.inJustDecodeBounds = false;

        return BitmapFactory.decodeByteArray(data, 0, data.length, tempOptions);
    }

    /**
     * 取得资源图片的sampleSize
     *
     * @param context
     * @param resource
     * @param maxWidth
     * @param maxHeight
     * @param options
     * @return
     */
    private static Bitmap getBitmapBySampleSize(Context context, int resource, int maxWidth, int maxHeight, BitmapFactory.Options options) {
        BitmapFactory.Options tempOptions = new BitmapFactory.Options();
        tempOptions.inJustDecodeBounds = true;

        BitmapFactory.decodeResource(context.getResources(), resource, tempOptions);
        // Calculate inSampleSize
        int inSampleSize = calculateInSampleSize(tempOptions, maxWidth, maxHeight);

        if (options != null) {
            tempOptions = options;
        }
        tempOptions.inSampleSize = inSampleSize;
        // Decode bitmap with inSampleSize set
        tempOptions.inJustDecodeBounds = false;

        return BitmapFactory.decodeResource(context.getResources(), resource, tempOptions);
    }

    /**
     * 计算图片的sampleSize
     *
     * @param options
     * @param maxWidth
     * @param maxHeight
     * @return
     */
    private static int calculateInSampleSize(BitmapFactory.Options options, int maxWidth, int maxHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;

        if (height >= width) {
            final int heightRatio = Math.round((float) height
                    / (float) maxHeight);
            return heightRatio;
        } else {
            final int widthRatio = Math.round((float) width
                    / (float) maxWidth);
            return widthRatio;
        }
    }

    /**
     * 改变图片的尺寸
     *
     * @param newWidth
     * @param newHight
     * @param oldBitmap
     * @return
     */
    private static Bitmap changeBitmapSizeFixed(float newWidth, float newHight, Bitmap oldBitmap) {
        if (oldBitmap == null || oldBitmap.isRecycled()) {
            return null;
        }
        float bmpWidth = oldBitmap.getWidth();
        float bmpHeight = oldBitmap.getHeight();

        if (bmpWidth == newWidth && newHight == bmpHeight) {
            return oldBitmap;
        }
//        float scaleWidth = newWidth/bmpWidth;   
//        float scaleHeight = newHight/bmpHeight;   
//        
//        Matrix matrix = new Matrix();   
//        matrix.postScale(scaleWidth, scaleHeight);   
//        Bitmap bm=Bitmap.createBitmap(oldBitmap, 0, 0, oldBitmap.getWidth(), oldBitmap.getHeight(),   
//                matrix, true);   
//        Bitmap.createBitmap(source, x, y, width, height)
        Bitmap newBitmap = Bitmap.createScaledBitmap(oldBitmap, (int) newWidth, (int) newHight, true);
        oldBitmap.recycle();
        System.gc();
        return newBitmap;
    }

    /**
     * 取得测量尺寸
     *
     * @param width
     * @param height
     * @param maxWidth
     * @param maxHeight
     * @return
     */
    public static int[] getMeasureSize(int width, int height, int maxWidth, int maxHeight) {
        if (width <= maxWidth || height <= maxHeight) {
            return null;
        }
        int newHeight = 0;
        int newWidth = 0;
        if (width > height) {
            newHeight = (int) getHeightByNewWidth(maxWidth, width, height);
            newWidth = maxWidth;
        } else {
            newWidth = (int) getWidthByNewHeight(maxHeight, width, height);
            newHeight = maxHeight;
        }
        return new int[]{newWidth, newHeight};
    }

    /**
     * 取得新的宽度
     *
     * @param newWidth
     * @param oldWidth
     * @param oldHeight
     * @return
     */
    public static float getHeightByNewWidth(float newWidth, float oldWidth, float oldHeight) {
        //640 * 101
        float scale = oldHeight / oldWidth;
        return newWidth * scale;
    }

    /**
     * 取得新的高度
     *
     * @param newHeight
     * @param oldWidth
     * @param oldHeight
     * @return
     */
    public static float getWidthByNewHeight(float newHeight, float oldWidth, float oldHeight) {
        //640 * 101
        float scale = oldHeight / oldWidth;
        return newHeight / scale;
    }

    /**
     * 根据图片路径取得角度
     *
     * @param path
     * @return
     */
    public static int readPictureDegree(String path) {
        if (Tools.isEmpty(path) || !isFile(path)) {
            return 0;
        }
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 判断此路径是否为文件
     *
     * @param path
     * @return
     */
    public static boolean isFile(String path) {
        try {
            if (new File(path).isFile()) {
                return true;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return false;

    }

    /**
     * 取得旋转后的图片
     *
     * @param angle  角度
     * @param bitmap 源图
     * @return
     */
    public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {
        Matrix matrix = new Matrix();
        ;
        matrix.postRotate(angle);
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        bitmap.recycle();
        return resizedBitmap;
    }

    /**
     * 根据图片路径压缩图
     *
     * @param savePath  存储路径
     * @param imagePath 图片路径
     * @param maxWidth  最大宽度
     * @param maxHeight 最大高度
     * @param callback  图片压缩完成的回调接口
     */
    public static void compressBitmap(final String savePath, final String imagePath,
                                      final int maxWidth, final int maxHeight, final CompressBitmapCallback callback) {
        compressBitmap(savePath, null, imagePath, maxWidth, maxHeight, callback);
    }

    /**
     * 压缩图片
     *
     * @param savePath  存储图片的路径
     * @param bitmap    bitMap
     * @param maxWidth  最大宽度
     * @param maxHeight 最大高茺
     * @param callback  图片压缩完成的回调接口
     */
    public static void compressBitmap(final String savePath, final Bitmap bitmap,
                                      final int maxWidth, final int maxHeight, final CompressBitmapCallback callback) {
        compressBitmap(savePath, bitmap, null, maxWidth, maxHeight, callback);
    }

    /**
     * 压缩图片
     *
     * @param savePath
     * @param bitmap
     * @param imagePath
     * @param maxWidth
     * @param maxHeight
     * @param callback
     */
    private static void compressBitmap(final String savePath, final Bitmap bitmap, final String imagePath,
                                       final int maxWidth, final int maxHeight, final CompressBitmapCallback callback) {
        new Thread() {
            @Override
            public void run() {
                if (!TextUtils.isEmpty(imagePath)) {
                    Bitmap bm = null;
                    if (imagePath != null) {
                        if (maxWidth > 0 && maxHeight > 0) {
                            bm = BitmapUtils.getBitmap(imagePath, maxWidth, maxHeight, null);//取到图片

                        } else {
                            bm = BitmapFactory.decodeFile(imagePath);
                        }
                    } else if (bitmap != null && !bitmap.isRecycled()) {
                        bm = BitmapUtils.changeBitmapSize(maxWidth, maxHeight, bitmap);
                    } else {
                        callback.compress(null);
                        return;
                    }

                    if (bm != null && !bm.isRecycled()) {
                        int angle = BitmapUtils.readPictureDegree(imagePath);//取得角度
                        MyLog.d(TAG, "图片的角度：" + angle);
                        if (angle > 0) {
                            bm = BitmapUtils.rotaingImageView(angle, bm);
                        }

                        String extensionName = FileUtil.getExtensionName(imagePath);
                        CompressFormat format = CompressFormat.PNG;
                        if (BitmapUtils.EXTENSION_IMG_JPEG.equalsIgnoreCase(extensionName)) {
                            MyLog.d(TAG, "图片类型为：  jpg");
                            format = CompressFormat.JPEG;
                        } else {
                            format = CompressFormat.PNG;
                            MyLog.d(TAG, "图片类型为：  png");
                        }

                        String localPath = FileUtil.saveBitmap(savePath, bm, format, extensionName);

                        callback.compress(localPath);
                    }
                    if (bm != null) {
                        bm.recycle();
                    }
                }
            }
        }.start();
    }

    /**
     * 取得图片的BAse64格式
     *
     * @param imagePath
     * @param callback
     */
    public static void getBitmapBase64(final String imagePath,
                                       final CompressBase64Callback callback) {
        String[] imgaePathArrary = new String[]{imagePath};
        getBitmapBase64(imgaePathArrary, callback, 600, 800, 100);
    }

    /**
     * 取得图片的Base64 格式
     *
     * @param imgaePathArrary
     * @param callback        callback
     * @param maxWidth
     * @param maxHeight
     * @param quality         70 - 100
     * @return
     */
    public static String getBitmapBase64(final String[] imgaePathArrary, final CompressBase64Callback callback,
                                         final int maxWidth, final int maxHeight, final int quality) {
        new Thread() {
            @Override
            public void run() {
                String[] resultBase64 = null;
                if (imgaePathArrary != null && imgaePathArrary.length > 0) {
                    resultBase64 = new String[imgaePathArrary.length];
                    for (int i = 0; i < imgaePathArrary.length; i++) {
                        resultBase64[i] = bitmapToBase64(imgaePathArrary[i], maxWidth, maxHeight, quality);
                    }
                    callback.finish(resultBase64);
                    ;
                } else {
                    callback.finish(null);
                }
            }
        }.start();
        return null;
    }

    /**
     * 将bitmap转成Base64数据
     *
     * @param imagePath
     * @param maxWidth
     * @param maxHeight
     * @param quality
     * @return
     */
    private static String bitmapToBase64(final String imagePath,
                                         final int maxWidth, final int maxHeight, final int quality) {

        if (!TextUtils.isEmpty(imagePath)) {
            Bitmap bm = null;
            if (imagePath != null) {
                if (maxWidth > 0 && maxHeight > 0) {
                    bm = BitmapUtils.getBitmap(imagePath, maxWidth, maxHeight, null);
                } else {
                    bm = BitmapFactory.decodeFile(imagePath);
                }
            }

            if (bm != null && !bm.isRecycled()) {
                int angle = BitmapUtils.readPictureDegree(imagePath);
                if (angle > 0) {
                    bm = BitmapUtils.rotaingImageView(angle, bm);
                }

            }

            return bitmapToBase64(bm, quality);

        }

        return null;
    }

    /**
     * 将bitmap转成Base64数据
     *
     * @param bitmap
     * @param quality
     * @return
     */
    private static String bitmapToBase64(Bitmap bitmap, final int quality) {

        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(CompressFormat.JPEG, quality, baos);

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);

                result = result.replaceAll("\n", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 将Base64转成BitMap
     *
     * @param base64Data
     * @return
     */
    public static Bitmap base64ToBitmap(String base64Data) {
        byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    /**
     * 压缩图片完成的回调接口
     *
     * @author Administrator
     */
    public static interface CompressBitmapCallback {
        /**
         * 图片压缩的回调
         *
         * @param imagePath 图片的路径
         */
        public void compress(String imagePath);
    }

    /**
     * 压缩成Base64完成的回调接口
     *
     * @author Administrator
     */
    public static interface CompressBase64Callback {
        /**
         * 压缩完成的回调
         *
         * @param base64
         */
        public void finish(String[] base64);
    }


    /**
     * 将彩色图转换为纯黑白二色
     *
     * @param
     * @return 返回转换好的位图
     */
    public static Bitmap convertToBlackWhite(Bitmap bmp) {
        int width = bmp.getWidth(); // 获取位图的宽
        int height = bmp.getHeight(); // 获取位图的高
        MyLog.d(TAG, "bitmap  width: " + width + "          height: " + height);
        int[] pixels = new int[width * height]; // 通过位图的大小创建像素点数组

        bmp.getPixels(pixels, 0, width, 0, 0, width, height);//取得空的bitmap
        int alpha = 0xFF << 24;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];

                //分离三原色
                int red = ((grey & 0x00FF0000) >> 16);
                int green = ((grey & 0x0000FF00) >> 8);
                int blue = (grey & 0x000000FF);

                //转化成灰度像素
                grey = (int) (red * 0.3 + green * 0.59 + blue * 0.11);
                grey = alpha | (grey << 16) | (grey << 8) | grey;
                pixels[width * i + j] = grey;
            }
        }
        //新建图片
        Bitmap newBmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        //设置图片数据
        newBmp.setPixels(pixels, 0, width, 0, 0, width, height);

        Bitmap resizeBmp = ThumbnailUtils.extractThumbnail(newBmp, width, height);
        return resizeBmp;
    }
}
